import { Column, Entity, BeforeInsert, BeforeUpdate, PrimaryGeneratedColumn, ManyToMany, JoinTable } from 'typeorm';
import { Exclude } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';
import * as bcrypt from 'bcryptjs'
import { RoleEntity } from 'src/role/entities/role.entity'
import { MenuEntity } from 'src/menu/entities/menu.entity'

@Entity('user')
export class UserEntity {
  @ApiProperty({ description: '用户id' })
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ApiProperty({ description: '用户名' })
  @Column({ length: 100 })
  username: string;

  @ApiProperty({ description: '用户昵称' })
  @Column({ length: 100, nullable: true })
  nickname: string;

  @Exclude()
  @Column({ select: false })
  password: string;

  @ApiProperty({ description: '用户头像' })
  @Column({ default: null })
  avatar: string;


  @ApiProperty({ description: '用户手机号' })
  @Column({ default: null })
  phone: string;

  @ApiProperty({ description: '用户邮箱' })
  @Column({ default: null })
  email: string;

  @Column({ default: 1 })
  status: number;


  @ApiProperty({ description: '用户角色--admin,manager,roleManage,editor,user' })
  @ManyToMany(() => RoleEntity, role => role.users, { cascade: true })
  @JoinTable({
    name: 'user_roles',
    joinColumns: [
      { name: 'userId', referencedColumnName: 'id' },
    ],
    inverseJoinColumns: [
      { name: 'roleId', referencedColumnName: 'id' },
    ],
  })
  roles: RoleEntity[];

  @ApiProperty({ description: '用户菜单权限' })
  @ManyToMany(() => MenuEntity, menu => menu.users)
  @JoinTable({
    name: 'user_menus',
    joinColumns: [
      { name: 'userId', referencedColumnName: 'id' }
    ],
    inverseJoinColumns: [
      { name: 'menuId', referencedColumnName: 'id' }
    ]
  })
  menus: MenuEntity[];

  @Column({ type: 'timestamp', name: `create_time`, default: () => 'CURRENT_TIMESTAMP' })
  createTime: Date;

  @Column({ type: 'timestamp', name: `update_time`, default: () => 'CURRENT_TIMESTAMP' })
  updateTime: Date;

  //save()方法不会触发这个生命周期
  @BeforeInsert()
  async encryptPwd() {
    if (!this.password) return;
    // 使用bcrypt加密密码
    this.password = await bcrypt.hashSync(this.password, 10);
  }

  @BeforeUpdate()
  async encryptNewPwd() {
    if (!this.password) return;
    // 使用bcrypt加密密码
    this.password = await bcrypt.hashSync(this.password, 10);
  }
}
